﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Globalization;

namespace SRTM_Prepare
{
    class Program
    {
        static int ncols = 0;
        static int nrows = 0;
        static double xllcorner = 0;
        static double yllcorner = 0;
        static double cellsize = 0;
        static double noDataValue = -9999;

        //51.097378,6.769024
        //50.811142,7.58595
        static double Left = 6.223755;
        static double Top = 51.503614;
        static double Bottom = 50.431268;
        static double Right = 8.231506;
        //static double Left = 6.117627;
        //static double Top = 53.559889;
        //static double Right = 14.588086;
        //static double Bottom = 47.820532;

        static double hscale = 0.00083333333333333;
        static double vscale = 0.00083333333333333;

        static Int16[] dgrid;
        static int lastInd = 0;

        static void Main(string[] args)
        {
            int count = (int)((Right - Left) / hscale + 1) * (int)((Top - Bottom) / vscale + 1);
            dgrid = new Int16[count + 13];

            //String filePath = @"C:\Users\Nicolas\Desktop\STRM\entpackt\";
            String filePath = @"D:\Archiv\STRM\entpackt\";

            Console.WriteLine("Start STRM-Data To Bin (c)2012 by Nicolas Kruse");

            string[] Files = System.IO.Directory.GetFiles(filePath);

            foreach (string file in Files)
            {
                if (file.EndsWith(".asc"))
                {
                    Console.WriteLine("Phrase File: " + file + "...");
                    phrase(file);
                }
            }

            int intLeft = (int)(Left * 10E6);
            int intRight = (int)(Right * 10E6);
            int intBottom = (int)(Bottom * 10E6);
            int intTop = (int)(Top * 10E6);
            int intHscale = (int)((Right - Left) / hscale + 1);
            int intVscale = (int)((Top - Bottom) / vscale + 1);

            dgrid[0] = (Int16)(intLeft & 0xFFFF);
            dgrid[1] = (Int16)(intLeft >> 16);
            dgrid[2] = (Int16)(intRight & 0xFFFF);
            dgrid[3] = (Int16)(intRight >> 16);
            dgrid[4] = (Int16)(intTop & 0xFFFF);
            dgrid[5] = (Int16)(intTop >> 16);
            dgrid[6] = (Int16)(intBottom & 0xFFFF);
            dgrid[7] = (Int16)(intBottom >> 16);
            dgrid[8] = (Int16)(intHscale & 0xFFFF);
            dgrid[9] = (Int16)(intHscale >> 16);
            dgrid[10] = (Int16)(intVscale & 0xFFFF);
            dgrid[11] = (Int16)(intVscale >> 16);

            Console.WriteLine("Write to file...");

            var outputFile = new FileStream(filePath + "binSRTM.dat", FileMode.Create);
            var writer = new BinaryWriter(outputFile);

            foreach (Int16 item in dgrid) 
            { 
                writer.Write(item); 
            }

            writer.Close();
            outputFile.Close();

            Console.WriteLine("Finished.");

            Console.Read();
        }

        static void phrase(string path)
        {
            var data = ReadFile(path);
            int lastChar = -1;
            string lastEntr = "";
            bool contentData = false;
            bool lastIsNum = false;
            bool cancelFile = false;
            int coli = 0;
            int rowi = 0;

            NumberFormatInfo format = new NumberFormatInfo();
            format.NumberGroupSeparator = ",";
            format.NumberDecimalSeparator = "."; 

            for (int i = 0; i < data.Length; i++)
            {
                if (!char.IsLetterOrDigit(data[i]) && !char.IsPunctuation(data[i]))
                {
                    if (i > lastChar + 1)
                    {
                        var tempStr = data.Substring(lastChar+1, i - lastChar-1).Trim();

                        switch (lastEntr)
                        {
                            case "":
                                lastIsNum = false;
                                break;
                            case "ncols":
                                ncols = int.Parse(tempStr);
                                lastIsNum = false;
                                break;
                            case "nrows":
                                nrows = int.Parse(tempStr);
                                lastIsNum = false;
                                break;
                            case "xllcorner":
                                xllcorner = int.Parse(tempStr);
                                lastIsNum = false;
                                break;
                            case "yllcorner":
                                yllcorner = int.Parse(tempStr);
                                lastIsNum = false;
                                break;
                            case "cellsize":
                                cellsize = double.Parse(tempStr, format);
                                lastIsNum = false;
                                break;
                            case "NODATA_value":
                                noDataValue = int.Parse(tempStr);
                                lastIsNum = false;
                                break;

                            default:
                                if (lastIsNum)
                                {
                                    if (xllcorner > Right || xllcorner + ncols * cellsize < Left) cancelFile = true;
                                    if (yllcorner > Top || yllcorner + nrows * cellsize < Bottom) cancelFile = true;
                                    contentData = true;
                                }
                                lastIsNum = true;
                                break;
                        }

                        if (cancelFile) break;


                        if (contentData)
                        {

                            double x = xllcorner + rowi * cellsize;
                            double y = yllcorner + nrows * cellsize - coli * cellsize;

                            AddDataPoint(double.Parse(lastEntr), x, y);

                            rowi++;
                            if (rowi > nrows -1)
                            {
                                rowi = 0;
                                coli++;
                            }
                        }

                        lastEntr = tempStr;
                    }
                    lastChar = i;
                }
            }
        }

        static double lasty;

        static private void AddDataPoint(double Altitude, double x, double y)
        {
            if (x >= Left && x < Right + hscale && y >= Bottom && y < Top + vscale)
            {
                int index = 12;

                index += (int)((x - Left) / hscale);
                index += (int)((Top - y) / vscale) * (int)((Right - Left) / hscale + 1);

                if (lastInd + 2 == index)
                {
                    lastInd = index;
                }

                lastInd = index;
                dgrid[index] = (short)Altitude;


                if (y != lasty)
                {
                    if (Altitude > -9999)
                        Console.WriteLine(y + "; " + x + "; " + Altitude);
                    lasty = y;
                }
            }
        }

        static private string ReadFile(String sFilename)
        {
            string sContent = "";

            if (File.Exists(sFilename))
            {
                StreamReader myFile = new StreamReader(sFilename, System.Text.Encoding.Default);
                sContent = myFile.ReadToEnd();
                myFile.Close();
            }
            return sContent;
        }

    }
}
